
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author David Beaver
 */
public class Response {
    private Request request;
    private ServerConfig config;
    private XmlParser commandBuilder;
    private String response;

    public Response(){
        this.request = new Request();
        this.response = new String();
    }

    public Response(ServerConfig config){
        this.config = config;
        this.request = new Request();
        this.response = new String();
    }

    /* Saves a copy of the request */
    public void processRequest(Request request){
        this.request = request;
        String command = this.request.getCommand();
        if(command.equals("create-job")){
            System.out.println("EXEC: Creating Job #"+this.request.getID()+"...");
            String [] dirs = new String[3];
            //create 3 directories
            dirs[0] = this.config.resolveAlias("jobs").concat(this.request.getID().toString()); //parent job folder
            dirs[1] = dirs[0].concat("/input"); //input sub-folder
            dirs[2] = dirs[0].concat("/output"); //output sub-folder
            this.response = "NO";
            int step = 1;
            boolean success = false;
            for(String dir : dirs){ //for each directory
                System.out.print("EXEC:\t["+step+"]Make "+dir+"...");
                step++;
                success = (new File(dir).mkdir()); //make the directory
                if(!success){ //if the make was unsuccessful
                    System.out.print("ERROR\n");
                }
                System.out.print("OK\n");
                //job directories setup
            }
            try {
                if(success == true){
                    System.out.print("EXEC:\t[4]Saving execute.xml...");
                    BufferedWriter out = new BufferedWriter(new FileWriter(dirs[0]+File.separator+"execute.xml")); //prepare to save execute.xml
                    out.write(this.request.getXML()); //save the xml
                    out.close(); //close the file
                    System.out.print("OK\n");
                    this.response = "OK";
                }
            }catch(IOException ex){
                
            }    
            
        }else if(command.equals("execute")){
            System.out.println("EXEC: Executing job...");
            String alias = this.request.getPath();
            String path = this.config.resolvePath(alias);
            this.commandBuilder = new XmlParser(path + "execute.xml", this.config);
            String comm = commandBuilder.getExecutableCommand();
            //comm = "/home/bagside/Documents/msroll -f /jobs/5678/input/123A.pdb -r /jobs/5678/input/radius2.5 1> 123A.c3p 2> log.msroll";
            System.out.println(comm);
            CommandHandler jobStarter = new CommandHandler(this.config);
            String status = jobStarter.execCommand(comm, path+"output");
            if(status.equals("SUCCESS")){
                this.response = "OK";
            }else{
                this.response = "NO";
            }
        }else if(command.equals("job-status")){
            System.out.println("EXEC: Checking Job #"+this.request.getID()+" status...");
            String alias = this.request.getPath();
            String path = this.config.resolvePath(alias);
            path += "status.txt";
            System.out.print("EXEC:\t[1]Opening "+path+"...");
            File statusFile = new File(path);
            if(statusFile.exists()){
                FileInputStream fstream = null;
                try {
                    fstream = new FileInputStream(statusFile);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Response.class.getName()).log(Level.SEVERE, null, ex);
                }
                System.out.print("OK\nEXEC:\t[2]Reading job status...");
                // Get the object of DataInputStream
                DataInputStream in = new DataInputStream(fstream);
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                String strLine;
                try {
                    String status = new String();
                    //Read File Line By Line
                    if((strLine = br.readLine()) != null)   {
                      // Print the content on the console
                      status = strLine;
                    }
                    in.close();
                    this.response = status;
                    System.out.print(status+"\n");
                }catch(IOException ex){
                    
                }
            }
        }else if(command.equals("system-status")){
            CommandHandler commandExecutor = new CommandHandler(config); //
            this.response = commandExecutor.execCommand("system-status","");
        }else if(command.equals("public?")){
            System.out.print("EXEC: Checking public status...");
            this.response = "NO";
            if(this.config.isPublic()){
                this.response = "YES";
            }
            System.out.print(this.response+"\n");
        }else if(command.equals("gpu?")){
            System.out.print("EXEC: Checking GPU support...");
            this.response = "NO";
            if(this.config.hasGPU()){
                response = "YES";
            }
            System.out.print(this.response+"\n");
        }else if(command.equals("availability")){
            System.out.println("EXEC: Checking availability...OK");
            this.response = "OK"; //response is OK
        }    
    }

    public void sendResponse(OutputStream serverOutput){
        System.out.print("EXEC: Sending response to Server Manager...");
        try {
            serverOutput.write(this.response.getBytes(), 0, this.response.length()); //send response
        } catch (IOException ex) {
            Logger.getLogger(Response.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.print("OK\n");
    }
}
